package lynch.display 
{
	import Elegant.utils.InitObject;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.errors.IllegalOperationError;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	
	/**
	 * a Image with 9 scale Grid
	 * @author 小痛
	 */
	public class Scale9Image extends Bitmap
	{
		private var _source:BitmapData;
		private var _scale9Grid:Rectangle;
		
		/**
		 * 
		 * @param	source
		 * @param	scale9Grid
		 * @param	objectVars	<li><strong> width : int </strong></li>
		 * 						<li><strong> height : int </strong></li>
		 */
		public function Scale9Image(source:BitmapData, scale9Grid:Rectangle, objectVars:Object = null) 
		{
			super();
			
			_source = source;
			_scale9Grid = scale9Grid;
			
			updateBitmapData(InitObject.getInt(objectVars, "width", source.width),
				InitObject.getInt(objectVars, "height", source.height));
		}
		
		/**
		 * 
		 */
		public function dispose():void 
		{
			_source = null;
			_scale9Grid = null;
		}
		
		/**
		 * 此段代码摘自sunbright的Zoom9Grid
		 */
		public function updateBitmapData(_width:int, _height:int):void
		{
			if (_width == _source.width && _height == _source.height)
			{
				bitmapData = _source;
				return;
			}
			
			var bmd:BitmapData = new BitmapData(_width, _height, true, 0x0);
			bmd.lock();
			
			if(scale9Grid == null)
			{
				var mtx:Matrix = new Matrix(_width / _source.width, 0, 0, _height / _source.height);
				bmd.draw(_source, mtx);
			}
			else
			{
				var rows:Array = [0, scale9Grid.top, scale9Grid.bottom, _source.height];
				var cols:Array = [0, scale9Grid.left, scale9Grid.right, _source.width];
				
				var toRows:Array = [0, scale9Grid.top, _height - _source.height + scale9Grid.bottom, _height];
				var toCols:Array = [0, scale9Grid.left, _width - _source.width + scale9Grid.right, _width];
				
				var clipRect:Rectangle, matrix:Matrix, r:int, c:int, a:Number, d:Number;
				var r1:int, r2:int, c1:int, c2:int, tr1:int, tr2:int, tc1:int, tc2:int;
				
				for (c = 0; c < 3; ++c)
				{
					for(r = 0; r < 3; ++r)
					{
						r1 = rows[r];
						r2 = rows[r + 1];
						c1 = cols[c];
						c2 = cols[c + 1];
						tr1 = toRows[r];
						tr2 = toRows[r + 1];
						
						tc1 = toCols[c];
						tc2 = toCols[c + 1];
						clipRect = new Rectangle(tc1, tr1, tc2 - tc1, tr2 - tr1);
						a = c == 1 ? (clipRect.width / (c2 - c1)) : 1;
						d = r == 1 ? (clipRect.height / (r2 - r1)) : 1;
						matrix = new Matrix(a, 0, 0, d, tc1 - c1 * a, tr1 - r1 * d);
						bmd.draw(_source, matrix, null, null, clipRect, true);
					}
				}
			}
			
			bmd.unlock();
			bitmapData = bmd;
		}
		
		
		//--------------------getter / setter---------------
		/**
		 * get / set scale9Grid
		 */
		public function get scale9Grid():Rectangle 
		{
			return _scale9Grid;
		}
		
		public function set scale9Grid(value:Rectangle):void 
		{
			_scale9Grid = value;
		}
		
		/**
		 * @see #updateBitmapData()
		 */
		override public function set width(value:Number):void 
		{
			throw new IllegalOperationError("width can not be set directly, please use updateBitmapData()");
		}
		
		/**
		 * @see #updateBitmapData()
		 */
		override public function set height(value:Number):void 
		{
			throw new IllegalOperationError("width can not be set directly, please use updateBitmapData()");
		}
	}
}